package com.cicadasmall.builder.core;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.cicadasmall.builder.core.callback.ICallBack;
import com.cicadasmall.builder.core.config.MyDataSourceConfig;
import com.cicadasmall.builder.core.config.MyFileGenerateConfig;
import com.cicadasmall.builder.core.config.MyGlobalConfig;
import com.cicadasmall.builder.core.config.MyPackageConfig;
import com.cicadasmall.builder.core.fileout.UIApiFileOutConfig;
import com.cicadasmall.builder.core.fileout.UIRouteFileOutConfig;
import com.cicadasmall.builder.core.fileout.UIViewFileOutConfig;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * GeneratorBuilder
 *
 * @author Jin
 */
public class GeneratorBuilder extends Generator {

    private DataSourceConfig dataSourceConfig;

    private MyPackageConfig packageConfig;

    private MyGlobalConfig globalConfig;

    private StrategyConfig strategyConfig;

    private InjectionConfig injectionConfig;

    /**
     * 包配置
     *
     * @param parent 包名
     * @param module 模块名
     * @return this
     */
    public GeneratorBuilder packageConfig(String parent, String module) {
        packageConfig = new MyPackageConfig();
        packageConfig.setParent(parent);
        packageConfig.setModuleName(module);
        return this;
    }

    /**
     * 全局配置
     *
     * @param doOutPutDir         接口文件输出目录
     * @param daoOutPutDir         业务逻辑文件输出目录
     * @param logicOutPutDir         业务逻辑文件输出目录
     * @param openOutPutDir        是否打开文件输出目录
     * @param enableSwagger        是否启用swagger 注解
     * @param enableBaseResultMap  是否包含 BaseResultMap
     * @param enableBaseColumnList 是否包含 BaseColumnList
     * @param overrideFile         是否覆盖文件
     * @param dateType             日期类型
     * @param author               作者
     * @return this
     */
    public GeneratorBuilder globalConfig(String doOutPutDir,String daoOutPutDir,String logicOutPutDir, boolean openOutPutDir, boolean enableSwagger, boolean enableBaseResultMap, boolean enableBaseColumnList, boolean overrideFile, DateType dateType, String author) {
        globalConfig = new MyGlobalConfig();
        globalConfig.setLogicFileOutputDir(logicOutPutDir);
        globalConfig.setDoFileOutputDir(doOutPutDir);
        globalConfig.setDaoFileOutputDir(daoOutPutDir);
        globalConfig.setOpen(openOutPutDir);
        globalConfig.setSwagger2(enableSwagger);
        globalConfig.setBaseResultMap(enableBaseResultMap);
        globalConfig.setBaseColumnList(enableBaseColumnList);
        globalConfig.setFileOverride(overrideFile);
        globalConfig.setDateType(dateType);
        globalConfig.setAuthor(author);
        return this;
    }

    /**
     * 数据源配置
     *
     * @param dataSource 数据源
     * @return this
     */
    public GeneratorBuilder dataSourceConfig(DataSource dataSource) {
        dataSourceConfig = new MyDataSourceConfig(dataSource);
        dataSourceConfig.setDbType(DbType.MYSQL);
        return this;
    }

    /**
     * 生成策略配置
     *
     * @return this
     */
    public GeneratorBuilder strategyConfig(String tablePrefix, String tableName, boolean entityLombokModel, boolean restControllerStyle) {
        strategyConfig = new StrategyConfig();
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setEntityLombokModel(entityLombokModel);
        strategyConfig.setRestControllerStyle(restControllerStyle);
        strategyConfig.setTablePrefix(tablePrefix);
        strategyConfig.setInclude(tableName);
        strategyConfig.setSuperServiceImplClass(packageConfig.getParent() + StringPool.DOT + "common" + StringPool.DOT + "base" + StringPool.DOT + "service" + StringPool.DOT + "BaseService");
        return this;
    }


    /**
     * 自定义生成配置
     *
     * @return this
     */
    public GeneratorBuilder injectionConfig() {
        injectionConfig = new MyFileGenerateConfig();
        List<FileOutConfig> fileOutList = new ArrayList<>();
        fileOutList.add(new UIApiFileOutConfig());
        fileOutList.add(new UIRouteFileOutConfig());
        fileOutList.add(new UIViewFileOutConfig());
        injectionConfig.setFileOutConfigList(fileOutList);
        injectionConfig.setMap(new HashMap<>());
        return this;
    }

    public GeneratorBuilder setCallBack(ICallBack callBack) {
        this.callBack = callBack;
        return this;
    }

    public static GeneratorBuilder build() {
        return new GeneratorBuilder();
    }

    @Override
    public void execute() {
        Generator generator = new Generator();
        Assert.notNull(packageConfig, "packageConfig 未配置");
        generator.setPackageInfo(packageConfig);
        Assert.notNull(dataSourceConfig, "dataSourceConfig 未配置");
        generator.setDataSource(dataSourceConfig);
        Assert.notNull(globalConfig, "globalConfig 未配置");
        generator.setGlobalConfig(globalConfig);
        Assert.notNull(strategyConfig, "strategyConfig 未配置");
        generator.setStrategy(strategyConfig);
        generator.setCfg(injectionConfig);
        generator.callBack = callBack;
        generator.execute();
    }

}
